<!-- 
    time：20024-4-20
    name：meidusa 
    role：大文件分片上传
 -->

<template>
    <div class="bigfile-slicing-box">
        <input type="file" ref="fileDom" @change="changeFile">
    </div>
</template>

<script setup lang='ts'>
// import SparkMD5 from 'spark-md5'
import { ref } from 'vue';
let fileDom = ref()
const CHUNK_SIZE = ref(1024 * 1024 * 1) // 每一片的大小，5M

/**
 * 获取files对象
 * @param e 
 */
const changeFile = async (e: any) => {
    const file = e.target.files[0]
    const chunks = await cutFile(file)
    uploadFiles(chunks)
}

/**
 * 切片
 * @param file 文件对象
 */
const cutFile = (file: any) => {
    const chunks = []
    for (let i = 0; i < file.size; i += CHUNK_SIZE.value) {
        chunks.push(file.slice(i, i + CHUNK_SIZE.value))
    }
    return chunks
}

/**
 * 上传
 * @param chunks 所有切片
 */
const uploadFiles = (chunks: any) => {
    // 1. 批量上传,通过promise.all
    // 2. formDate方式进行上传  file标识,后端需要同标识进行合并,可以是hash可以是索引
    const list = []
    for (let i = 0; i < chunks.length; i++) {
        const formData = new FormData()
        formData.append('index', chunks[i].index)
        formData.append('fileName', 'file')
        formData.append('file', chunks[i]) // 写在最后面,不然有坑
        list.push(fetch('http://localhost:3000/upload', {
            method: 'POST',
            body: formData
        }))
    }
    Promise.all(list).then(_res => {
        // 3.上传成功后通知后端合并文件
        fetch('http://localhost:3000/merge', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({
                fileName: 'mdsfile'
            })
        })
    })
}
</script>

<style lang="scss" scoped></style>